/**
   Copyright 2010 Carlo Alberto Degli Atti (lord kada)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

package it.concept.pin.proxy;

import it.concept.pin.annotations.Pin;

import java.lang.reflect.*;

public class ProxyWrapper implements InvocationHandler {

	private Object target;

	public static Object createProxy( Class<?> classToConvertBack, Object target ) {

		return Proxy.newProxyInstance( classToConvertBack.getClassLoader(), new Class[] { classToConvertBack }, new ProxyWrapper( target ) );

	}

	/**
	 * Provate constructor
	 * @param target
	 */
	private ProxyWrapper( Object target ) {

		this.target = target;

	}
	
	public Object invoke( Object proxy, Method method, Object[] args ) {

		Object result = null;

		Class<?> argClasses[] = null;

		if ( args != null ) {

			argClasses = new Class<?>[ args.length ];

			for ( int i = 0; i < args.length; i++ )
				argClasses[ i ] = args[ i ].getClass();

		}

		try {

			Method proxyMethod = target.getClass().getMethod( method.getName(), argClasses );

			result = proxyMethod.invoke(target, args);
			
			Pin pinAnnotation = result.getClass().getAnnotation( Pin.class );
			
			if ( pinAnnotation != null ) 
				
				return ProxyWrapper.createProxy( Class.forName( pinAnnotation.javaInterfaceName() ), result );
				
			return result;

		} catch ( Exception e ) {

			throw new RuntimeException( e );
			
		}

	}

}